﻿

using System;
using PathologicalGames;
using UnityEngine;

/// <summary>
/// 对象池工具
/// </summary>
public static class PoolMgr
{
    public static GameObject Root { get; private set; }

    public static void Init()
    {
        if (Root)
        {
            Debug.LogError("对象池只能初始化一次");
            return;
        }
        Root = new GameObject("PoolMgr");
    }

    /// <summary>
    /// 创建对象池
    /// </summary>
    /// <param name="poolName"></param>
    /// <param name="prefab"></param>
    /// <param name="initAction"></param>
    /// <param name="initPool">初始化池数据</param>
    /// <returns></returns>
    public static SpawnPool CreatePool(string poolName,Transform prefab,Action<Transform> initAction = null,PrefabPool initPool = null)
    {
        SpawnPool pool = PoolManager.Pools.Create(poolName);
        pool.dontDestroyOnLoad = true;
        pool.poolName = poolName;
        
        pool.group.name = poolName+"_Group";
        pool.group.SetParent(Root.transform);
        initAction?.Invoke(pool.@group);
        // prefab.parent = Root.transform;
        // prefab.gameObject.SetActive(false);
        PrefabPool prefabPool = initPool;
        if (prefabPool == null)
        {
            //创建预设
            prefabPool = new PrefabPool(prefab);
            //默认初始化个数
            prefabPool.preloadAmount = 0;
            //是否开启自动清理模式
            prefabPool.cullDespawned = true;
            //自动清理，但保留几个对象不清理
            prefabPool.cullAbove = 2;
            //每过多久执行一遍自动清理，单位秒
            prefabPool.cullDelay = 10;
            //每次自动清理对象数
            prefabPool.cullMaxPerPass = 5;
            //是否限制Instance
            prefabPool.limitInstances = false;
            //限制缓存池里最大的Prefab的数量，!!!和上面的preloadAmount是有冲突的，如果同时开启则以limitAmout为准
            prefabPool.limitAmount = 200;
            //如果我们限制了缓存池里面只能有10个Prefab，如果不勾选它，那么你拿第11个的时候就会返回null。如果勾选它在取第11个的时候他会返回给你前10个里最不常用的那个
            prefabPool.limitFIFO = false;
        }
        pool.CreatePrefabPool(prefabPool);
        return pool;
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <param name="groupName">组名</param>
    /// <param name="keyName">取值键名</param>
    /// <param name="prefab">池prefab</param>
    /// <param name="initAction"></param>
    /// <param name="initPool"></param>
    /// <returns></returns>
    public static SpawnPool CreatePool(string groupName,string resPath,Transform prefab,Action<Transform> initAction = null,PrefabPool initPool = null)
    {
        SpawnPool pool = PoolManager.Pools.Create(resPath);
        pool.dontDestroyOnLoad = true;
        pool.poolName = resPath;
        
        pool.group.name = groupName;
        pool.group.SetParent(Root.transform);
        initAction?.Invoke(pool.@group);
        // prefab.parent = Root.transform;
        // prefab.gameObject.SetActive(false);
        PrefabPool prefabPool = initPool;
        if (prefabPool == null)
        {
            //创建预设
            prefabPool = new PrefabPool(prefab);
            //默认初始化个数
            prefabPool.preloadAmount = 0;
            //是否开启自动清理模式
            prefabPool.cullDespawned = true;
            //自动清理，但保留几个对象不清理
            prefabPool.cullAbove = 2;
            //每过多久执行一遍自动清理，单位秒
            prefabPool.cullDelay = 10;
            //每次自动清理对象数
            prefabPool.cullMaxPerPass = 5;
            //是否限制Instance
            prefabPool.limitInstances = false;
            //限制缓存池里最大的Prefab的数量，!!!和上面的preloadAmount是有冲突的，如果同时开启则以limitAmout为准
            prefabPool.limitAmount = 200;
            //如果我们限制了缓存池里面只能有10个Prefab，如果不勾选它，那么你拿第11个的时候就会返回null。如果勾选它在取第11个的时候他会返回给你前10个里最不常用的那个
            prefabPool.limitFIFO = false;
        }
        pool.CreatePrefabPool(prefabPool);
        return pool;
    }
    
    
    /// <summary>
    /// 根据模板预设获取新的预设
    /// </summary>
    /// <param name="poolName"></param>
    /// <param name="prefab"></param>
    /// <returns></returns>
    public static Transform GetPrefab(string poolName,Transform prefab)
    {
        return PoolManager.Pools[poolName].Spawn(prefab);
    }
    /// <summary>
    /// 根据预设名称获取新的预设
    /// </summary>
    /// <param name="poolName"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static Transform GetPrefab(string poolName,string name)
    {
        var prefab = PoolManager.Pools[poolName].prefabs[name];
        return PoolManager.Pools[poolName].Spawn(prefab);
    }
    
    /// <summary>
    /// 回池
    /// </summary>
    /// <param name="poolName"></param>
    /// <param name="prefab"></param>
    public static void RemovePrefab(string poolName,Transform prefab)
    {
        PoolManager.Pools[poolName].Despawn(prefab);
        prefab.SetParent(PoolManager.Pools[poolName].group);  
    }
}